package com.wetao.lib_common.exception;

import android.annotation.SuppressLint;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;

import com.wetao.lib_common.Constants;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

@SuppressLint("SimpleDateFormat")
public class CrashHandler implements UncaughtExceptionHandler {
	private static final String TAG = CrashHandler.class.getSimpleName();
	private UncaughtExceptionHandler mDefaultHandler;
	private static CrashHandler INSTANCE = new CrashHandler();
	private Context mContext;
	private Map<String, String> info = new HashMap<String, String>();
	private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");

	private CrashHandler() {

	}

	public static CrashHandler getInstance() {
		return INSTANCE;
	}

	public void init(Context context) {
		mContext = context;
		mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
		Thread.setDefaultUncaughtExceptionHandler(this);
	}

	public void uncaughtException(Thread thread, Throwable ex) {
		if (!handleException(ex) && mDefaultHandler != null) {
			mDefaultHandler.uncaughtException(thread, ex);
		} else {
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			Intent intent = new Intent();
			intent.setClassName("com.sunducation.wts.penbox.activity","com.sunducation.wts.penbox.activity.SplashActivity");
			@SuppressLint("WrongConstant")
			PendingIntent restartIntent = PendingIntent.getActivity(
					mContext.getApplicationContext(), 0, intent,
					Intent.FLAG_ACTIVITY_NEW_TASK);
			//退出程序
			AlarmManager mgr = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
			mgr.set(AlarmManager.RTC, System.currentTimeMillis(),
					restartIntent); //1秒钟后重启应用
			android.os.Process.killProcess(android.os.Process.myPid());
			System.exit(0);
		}
	}

	public boolean handleException(Throwable ex) {
		if (ex == null)
			return false;
		new Thread() {
			public void run() {
				Looper.prepare();
				Looper.loop();
			}
		}.start();
		collectDeviceInfo(mContext);
		saveCrashInfoToFile(ex);
		return true;
	}

	public void collectDeviceInfo(Context context) {
		try {
			PackageManager pm = context.getPackageManager();
			PackageInfo packageInfo = pm.getPackageInfo(context.getPackageName(),
					PackageManager.GET_ACTIVITIES);
			if (packageInfo != null) {
				String versionName = packageInfo.versionName == null ? "null"
						: packageInfo.versionName;
				String versionCode = packageInfo.versionCode + "";
				info.put("versionName", versionName);
				info.put("versionCode", versionCode);
			}
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}

		Field[] fields = Build.class.getDeclaredFields();
		for (Field field : fields) {
			try {
				field.setAccessible(true);
				info.put(field.getName(), field.get("").toString());
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
	}

	private String saveCrashInfoToFile(Throwable ex) {
		StringBuffer sb = new StringBuffer();
		for (Map.Entry<String, String> entry : info.entrySet()) {
			String key = entry.getKey();
			String value = entry.getValue();
			sb.append(key + "=" + value + "\r\n");
		}
		Writer writer = new StringWriter();
		PrintWriter pw = new PrintWriter(writer);
		ex.printStackTrace(pw);
		Throwable cause = ex.getCause();
		while (cause != null) {
			cause.printStackTrace(pw);
			cause = cause.getCause();
		}
		pw.close();
		String result = writer.toString();
		sb.append(result);
		saveErrToFile(sb);
		return null;
	}
	public static String  saveErrToFile(StringBuffer sb) {
		long timeStamp = System.currentTimeMillis();//获取时间戳
		String time = format.format(timeStamp);//格式化为标准日期格式
		String fileName = "crash-" + time + "-" + (timeStamp/1000) + ".log";
		/*if (Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED)) {*/
			try {
				//File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/penboxLog");
				File dir = new File(Constants.FILE_PATH + "/penboxLog");
				if (!dir.exists())
				{
					dir.mkdir();
				}
				File file = new File(dir,fileName);
				if (!file.exists()){
					file.createNewFile();
				}
				FileOutputStream fos = new FileOutputStream(file);
				fos.write(sb.toString().getBytes());
				fos.close();
				return fileName;
			} catch (Exception e) {
				e.printStackTrace();
			}
		//}
		return null;
	}
}